package com.customization.test.demo.workflowaction;

import com.alibaba.fastjson.JSONObject;
import com.customization.test.demo.util.ImageFileUtils;
import com.customization.test.demo.util.UploadImageSystemUtils;
import com.customization.test.demo.util.WorkflowToDocUtils;
import org.apache.log4j.Logger;
import weaver.conn.RecordSet;
import weaver.file.ImageFileManager;
import weaver.general.BaseBean;
import weaver.general.GCONST;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.interfaces.workflow.action.Action;
import weaver.soa.workflow.request.Property;
import weaver.soa.workflow.request.RequestInfo;

import java.io.*;
import java.nio.file.Files;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 流程归档后将本流程转为pdf和本流程的所有文件打包为zip上传至影像系统
 */
public class ArchiveFileProcessingAction extends BaseBean implements Action {

    private static final Logger logger = Logger.getLogger(ArchiveFileProcessingAction.class);
    private static final UploadImageSystemUtils upload = new UploadImageSystemUtils();

    @Override
    public String execute(RequestInfo requestInfo) {
        try {
            logger.info("开始：流程归档后将本流程转为pdf和本流程的所有文件打包为zip上传至影像系统");
            Map<String, String> map = new HashMap<>();
            // 获取表单主字段信息
            Property[] properties = requestInfo.getMainTableInfo().getProperty();
            for (Property property : properties) {
                String name = Util.null2String(property.getName());
                String value = Util.null2String(property.getValue());
                map.put(name, value);
            }
            //将流程表单转换为pdf
            //期间+所属银行+银行账户（文件名称）
            //组装pdf文件地址
            String pdfName = map.get("qj") + map.get("khyh") + map.get("yhzh") + "余额调节表";
            pdfName = "pdfName3";
            String pdfPath = GCONST.getRootPath() + "filesystem" + File.separatorChar+ "account";
            logger.info("第一步：组装pdf文件名字"+pdfName);
            logger.info("生成地址："+GCONST.getRootPath() + "filesystem" + File.separatorChar+ "account"+"上传到影像系统后可以根据该地址删除本地文件");
            WorkflowToDocUtils.createHtml(requestInfo,GCONST.getRootPath() + "filesystem" + File.separatorChar+ "account", pdfName);

            //将不需要的文件删除
            upload.DeleteFile(new File(pdfPath + File.separator + pdfName));
            logger.info("第二步：生成pdf文件，生成此文件需要添加字体文件");
            //创建pdf文件流
            File pdfFile = new File(pdfPath+File.separator+pdfName+ "_" + "pdf" + "." + "pdf");
            //获取附件id
            String[] enclosures = map.get("yhdzd").split(",");
            enclosures[0] = "38";
            enclosures[1] = "39";
            logger.info("所有附件id："+ Arrays.toString(enclosures));
            logger.info("去除空字符串：："+ Arrays.toString(enclosures));
            logger.info("第三步：将上传附件进行压缩" );
            logger.info("1：获取附件id："+ Arrays.toString(enclosures));
            //保存所有附件地址
            ArrayList<String> fileList = new ArrayList<>();
            UUID uuid = UUID.randomUUID();
            for (String enclosure : enclosures) {
                //根据附件id获取文件id和名字
                JSONObject fileData = getFileName(enclosure);
                if (fileData == null) {
                    continue;
                }
                //创建一个文件夹在存放附件，名字为所属银行+银行账户+UUID
                String folderPath = GCONST.getRootPath() + "filesystem" + File.separatorChar+ "account" +File.separatorChar + map.get("khyh") + map.get("yhzh") + uuid;
                logger.info("3.创建一个文件夹在存放附件:"+folderPath);
                File directory = new File(folderPath);
                // 如果文件夹不存在，则创建它
                if (!directory.exists()) {
                    boolean created = directory.mkdirs(); // 创建目录及其所有必需的父文件夹
                    if (created) {
                        //创建目录成功
                        logger.info("4.创建目录,存放附件");
                        ImageFileManager imageFileManager = new ImageFileManager();
                        imageFileManager.getImageFileInfoById(fileData.getIntValue("imagefileid"));
                        InputStream inputStream = imageFileManager.getInputStream();
                        saveToFile(inputStream, folderPath, fileData.getString("imagefilename"));
                        fileList.add(folderPath + File.separator + fileData.getString("imagefilename"));
                    } else {
                        logger.error("创建目录失败");
                    }
                } else {
                    logger.info("4.存放附件");
                    ImageFileManager imageFileManager = new ImageFileManager();
                    imageFileManager.getImageFileInfoById(fileData.getIntValue("imagefileid"));
                    InputStream inputStream = imageFileManager.getInputStream();
                    saveToFile(inputStream, folderPath, fileData.getString("imagefilename"));
                    fileList.add(folderPath + File.separator + fileData.getString("imagefilename"));
                }
            }
            //再将pdf文件存入文件夹
            String folderPath = GCONST.getRootPath() + "filesystem" + File.separatorChar+ "account" +File.separatorChar + map.get("khyh") + map.get("yhzh") + uuid;
            InputStream pdfinputStream = Files.newInputStream(pdfFile.toPath());
            saveToFile(pdfinputStream, folderPath, pdfName+"_pdf.pdf");
            fileList.add(folderPath + File.separator + pdfName+"_pdf.pdf");
            //zip文件名
            logger.info("——————————————————————————————————————————————————————————————————————————————————————");
            logger.info("第四步：压缩文件");
            String zipNamePath = GCONST.getRootPath() + "filesystem" + File.separatorChar+ "account" +File.separatorChar + map.get("khyh") + map.get("yhzh") + ".zip";
            //将pdf文件和银企对账单附件（打包为zip）
            logger.info("1：将pdf文件和银企对账单附件（打包为zip）地址："+zipNamePath);
            String[] fileStrList = fileList.toArray(new String[0]);
            //压缩文件
            zipFiles(fileStrList, zipNamePath);
            File zipFiles = new File(zipNamePath);
            //将文件压缩好之后，将将原文件删除
            upload.DeleteFile(new File(folderPath));
            //将文件打包好后存入流程表单
            User usr = requestInfo.getRequestManager().getUser();
            String requestid = requestInfo.getRequestid();
//            if (uploadFile(zipFiles,usr,requestid)){
//                logger.info("文件存储成功");
//            }else {
//                logger.info("文件存储失败");
//            }
//            //打包完毕后获取文件获取文件流推送至影像系统
            logger.info("——————————————————————————————————————————————————————————————————————————————————————");
            logger.info("第五步：打包完毕后获取文件获取文件流推送至影像系统");
            logger.info("File:"+zipFiles);
            Map<String,Object> params = new HashMap<>();
            params.put("useraccount","zhsysadmin");
            params.put("username",usr.getUsername());
            logger.info(usr.toString());
            String barcode = String.valueOf(requestInfo.getRequestManager().getBillid());
        } catch (Exception e) {
            logger.error("error:{}", e);
        }
        return "1";
    }

    /**
     * @param inputStream 文件流
     * @param saveDir     保存地址
     * @param fileName    文件名字
     */
    public static void saveToFile(InputStream inputStream, String saveDir, String fileName) throws IOException {
        String saveFilePath = saveDir + File.separator + fileName;
        logger.info("将文件保存至："+saveFilePath);
        FileOutputStream outputStream = new FileOutputStream(saveFilePath);

        // 从输入流读取数据并写入输出流
        int bytesRead;
        byte[] buffer = new byte[4096];
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        // 关闭流
        outputStream.close();
        inputStream.close();
    }

    /**
     * 根据附件id获取imagefileid和imagefilename
     */
    public JSONObject getFileName(String id) {
        RecordSet recordSet = new RecordSet();
        logger.info("根据附件id获取imagefileid和imagefilename");
        String sql = "select imagefileid,imagefilename from docimagefile where docid = '" + id+"'";
        recordSet.executeSql(sql);
        if (recordSet.next()) {
            JSONObject data = new JSONObject();
            data.put("imagefileid", recordSet.getString("imagefileid"));
            data.put("imagefilename", recordSet.getString("imagefilename"));
            logger.info("imagefileid："+recordSet.getString("imagefileid"));
            logger.info("imagefilename："+recordSet.getString("imagefilename"));
            return data;
        }
        return null;
    }

    public static void zipFiles(String[] files, String zipFilePath) {
        // 创建输出流
        try (FileOutputStream fos = new FileOutputStream(zipFilePath);
             ZipOutputStream zos = new ZipOutputStream(fos)) {

            // 将每个文件打包到ZIP文件中
            for (String filePath : files) {
                File file = new File(filePath);
                // 添加新条目到ZIP文件
                ZipEntry zipEntry = new ZipEntry(file.getName());
                zos.putNextEntry(zipEntry);

                // 从文件复制数据到ZIP输出流
                try (FileInputStream fis = new FileInputStream(file)) {
                    byte[] buffer = new byte[1024];
                    int length;
                    while ((length = fis.read(buffer)) > 0) {
                        zos.write(buffer, 0, length);
                    }
                }
                // 关闭当前条目，准备下一个文件
                zos.closeEntry();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //归档文件传入流程当中
    public boolean uploadFile(File file,User usr,String requestid) {
        ImageFileUtils imageFileUtils = new ImageFileUtils();
        try (FileInputStream fis = new FileInputStream(file)) {
            int docid = imageFileUtils.uploadFile(fis, usr, "24", file.getName());
            RecordSet recordSet = new RecordSet();
            String sql1 = "update formtable_main_128 set gdwjzip = '"+docid+"' where requestId = '"+requestid+"'";
            logger.info(sql1);
            return recordSet.executeUpdate(sql1);
        } catch (IOException e) {
            e.printStackTrace(); // 处理异常
            return false;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
